import { ObjectUtil } from '@/utils/ObjectUtil';
import { DateUtil } from '@/utils/DateUtil';
import { Options } from '@/components/Table/types';
import { isArray, isPromise } from '@/utils/General';

export const getTableOptions = <T>(options: Options<T>): Options<T> => {
  const _options: Options<T> = {};
  for (const key of ObjectUtil.keys(options)) {
    const clone = ObjectUtil.clone(options[key]);
    // 兼容 TS 警告
    if (clone) {
      // eslint-disable-next-line no-empty
      if (clone.readOnly === true || typeof clone.readOnly === 'function') {
      } else {
        clone.readOnly = false;
      }
      if (clone.type === 'binary-category') {
        if (clone.mappings.length !== 2) {
          console.warn(clone.mappings, '二分离散值的数据字典长度不为2');
        }
        if (!clone.format) {
          clone.format = value => {
            const map = clone.mappings.find(o => o.value === value);
            if (map) {
              return map.label;
            }
            return value as unknown as string;
          };
        }
      } else if (clone.type === 'category') {
        if (!clone.mappings) {
          console.warn(clone.mappings, '离散值的数据字典不存在');
          clone.mappings = [];
        }
        if (!clone.format && isArray(clone.mappings)) {
          clone.format = value => {
            const map = (clone.mappings as Array<{ label: string; value: unknown }>).find(o => o.value === value);
            if (map) {
              return map.label;
            }
            return value as unknown as string;
          };
        }
      } else if (clone.type === 'time') {
        if (!clone.format) {
          clone.format = value => {
            if (value instanceof Date) {
              return DateUtil.format(value);
            } else {
              return value as unknown as string;
            }
          };
        }
      } else {
        clone.type = 'value';
      }
      _options[key] = clone;
    }
  }
  return _options;
};

export const getTableOptionsAsync = async <T>(options: Options<T>): Promise<Options<T>> => {
  for (const key of ObjectUtil.keys(options)) {
    const option = options[key];
    if (option && option.type === 'category') {
      if (isPromise(option.mappings)) {
        (option.mappings as unknown as Array<{
          label: string;
          value: unknown;
        }>) = await (option.mappings as Promise<Array<{ label: string; value: unknown }>>);
      }
      option.format = value => {
        const map = (
          option.mappings as unknown as Array<{
            label: string;
            value: unknown;
          }>
        ).find(o => o.value === value);
        if (map) {
          return map.label;
        }
        return value as unknown as string;
      };
    }
  }
  return options;
};
